#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>

#define  FFINIT_FAILE             0
typedef struct{
    int id;
    char name[20];
    char path[40];
    int offset;
    int size;
    int shadow;
    int shadow_addr;
    int exec_addr;
    int protected;
}PARTITION_INFO;

typedef struct{
    int partition_number;
    PARTITION_INFO part;
}PARTITION_P;

int get_str(char *s1, char *s2)
{
    char *ss = s2;
    int i = 0;
    while(*s2 != '\0'){
        *s2++ = 0;
    }
    s2 = ss;
    while(1){
        if(*(s1+i) == '"') break;
        *(s2+i) = *(s1+i);
        i++;
    }
    return 0;
}

int x_sixteen(int i)
{
    int sixtn = 1;

    while(i--){
        sixtn = sixtn * 16;
    }
    return sixtn;
}

int x_16(char src)
{
    int tn = 0;

    if(src >= '0' && src <= '9')
        tn = src - '0';
    else{
        tn = src - 'A' + 10;
    }
    return tn;
}

int str_to_int(char *src)
{
    char str[20];
    int b;
    int data = 0;
    int k = 0;

    while(*src != 0x0A){
        str[k] = *src++;
        k++;
    }
    int i = k -1;
    k = 0;
    while(i >= 0){
        data += x_16(str[k]) * x_sixteen(i);
        i--;
        k++;
    }
    return data;
}

int read_ptt(PARTITION_P *part_q)
{
    int fd_ptt;
    int i;   //partition number
    int ptt_size = 0;
    char buffer[4096];
    char *partition_part = buffer;
    char BootNand[40];
    PARTITION_INFO partition[10];
    struct stat st;
    fd_ptt = open("./0x0A6300006E000261.ptt", O_RDONLY);
	if (fd_ptt == -1) {
		printf("Cannot open 0x0A6300006E000261.ptt!\n");	
		return FFINIT_FAILE;
	}
    if(!stat("./0x0A6300006E000261.ptt", &st))
        printf("0x0A6300006E000261.ptt size is %lld\n", st.st_size);

    ptt_size = read(fd_ptt, buffer, st.st_size);
    printf("ptt size = %d\n", ptt_size);

    //BootNand
    partition_part = strstr(partition_part, "BootNand");
    get_str((partition_part + sizeof("BootNand") + 1), BootNand);
    printf("BootNand %s\n", BootNand);

    while(1){
    //partition number
    partition_part = strstr(partition_part, "partition#");
    if(partition_part == NULL) break;
    //printf("partition_part %c", *(partition_part + sizeof("partition#") - 1));
    //printf("%c\n", *(partition_part + sizeof("partition#")));

    //id
    partition_part = strstr(partition_part, "partition_id");
    partition[i].id = str_to_int(partition_part + sizeof("partition_id") + 2);
    //printf("partition_id %d\n", partition[i].id);

    //name
    partition_part = strstr(partition_part, "partition_name");
    get_str((partition_part + sizeof("partition_name") + 1), partition[i].name);
    //printf("partition_name %s\n", partition[i].name);

    //path
    partition_part = strstr(partition_part, "partition_path");
    get_str((partition_part + sizeof("partition_path") + 1), partition[i].path);
    //printf("partition_path %s\n", partition[i].path);

    //offset
    partition_part = strstr(partition_part, "partition_offset");
    partition[i].offset = str_to_int(partition_part + sizeof("partition_offset") + 2);
    //printf("partition_offset %d\n", partition[i].offset);

    //size
    partition_part = strstr(partition_part, "partition_size");
    partition[i].size = str_to_int(partition_part + sizeof("partition_size") + 2);
    //printf("partition_size %d\n", partition[i].size);

    //shadow
    partition_part = strstr(partition_part, "partition_shadow");
    partition[i].shadow = str_to_int(partition_part + sizeof("partition_shadow") + 2);
    //printf("partition_shadow %d\n", partition[i].shadow);

    //shadow_address
    partition_part = strstr(partition_part, "partition_shadow_address");
    partition[i].shadow_addr = str_to_int(partition_part + sizeof("partition_shadow_address") + 2);
    //printf("partition_shadow_address %x\n", partition[i].shadow_addr);

    //exec_address
    partition_part = strstr(partition_part, "partition_exec_address");
    partition[i].exec_addr = str_to_int(partition_part + sizeof("partition_exec_address") + 2);
    //printf("partition_exec_address %d\n", partition[i].exec_addr);

    //protected
    partition_part = strstr(partition_part, "partition_protected");
    partition[i].protected = str_to_int(partition_part + sizeof("partition_protected") + 2);
    //printf("partition_protected %d\n", partition[i].protected);
    part_q[i].part = partition[i];
    i++;
    }

    close(fd_ptt);
    return i;
}

int main(void)
{
    PARTITION_P part_q[10];
    int partiton_number = 0;
    int i = 0;
    partiton_number = read_ptt(part_q); 

#if 1
    while(i < partiton_number){
        printf("partition %x\n", i+1);
        printf("partition_id 0x%x\n", part_q[i].part.id);
        printf("partition_name %s\n", part_q[i].part.name);
        printf("partition_path %s\n", part_q[i].part.path);
        printf("partition_offset 0x%x\n", part_q[i].part.offset);
        printf("partition_size 0x%x\n", part_q[i].part.size);
        printf("partition_shadow 0x%x\n", part_q[i].part.shadow);
        printf("partition_shadow_addr 0x%x\n", part_q[i].part.shadow_addr);
        printf("partition_exec_addr 0x%x\n", part_q[i].part.exec_addr);
        printf("partition_protected 0x%x\n", part_q[i].part.protected);
        part_q[i].partition_number = (i + 1);
        i++;
    }
#endif
    printf("partition is ok\n");



ERROR:
    return 0;
}
